package com.zyj.benchmark.sample;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

/**
 * 控制State 对象中的方法在什么时候被执行
 *
 * @Setup state中的方法如何被执行
 * @TearDown state中的方法如何被执行
 * Level.Trial 默认的执行策略, 整个基准测试只执行一次
 */
@State(Scope.Thread)
public class Sample_05_StateFixtures {

    double x;


    //启动benchmark之前做的准备工作
    @Setup //必须在@State下的类中才能使用, 实际上也算是@State管理的对象的生命周期一部分了
    public void prepare() {
        x = Math.PI;
    }

    //benchmark结束之后的检查工作
    @TearDown //必须在@State下的类中才能使用
    public void check() {
        //这里使用了断言
        assert x > Math.PI : "Nothing changed?";
    }

    @Benchmark
    public void measureRight() { //正确代码, 正常执行
        x++;
    }

    @Benchmark
    public void measureWrong() {
        //这里是错误代码示例, 会在 Benchmark执行完毕后 报错
        double x = 0;
        x++;
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(Sample_05_StateFixtures.class.getSimpleName())
                .forks(1)
                .jvmArgs("-ea") //开启断言检测；assertion在一般情况下是关闭的，通过java -ea 可以打开该功能，关闭为 -da
                .build();

        new Runner(opt).run();
    }

}
